<template>

  <van-row id="home-container">
    <HomeTop id="chat-top" :title="channelInfo.name" :showMemberInfo="showChannelMemberInfo"
             :height="windowHeight"></HomeTop>

    <van-col id="all-msg-content" span="24">

      <VirtualList ref="scrollBox" :listData="msgList"
                   :scrollHeight="windowHeight * 0.9"
                   :itemHeight="virtualMinSize"
                   v-slot:item="{item}"
                   v-if="msgList.length !==0"
                   :loadMoreFunction="msgListToTop"
      >
        <div :style=" { height: virtualMinSize  + 'px'}">
          <MessageListItem :source="item" :imageLoadFinish="onImageLoaded" :itemHeight="virtualMinSize"/>
        </div>
      </VirtualList>


    </van-col>
    <van-col span="24" id="chat-bottom">
      <div :style="{height: windowHeight * 0.05}">
        <van-field v-model="content"
                   style="width: 100%; color: #000; background-color:#f7f7f7 ;border: none;"
                   right-icon="guide-o"
                   left-icon="smile-o"
                   @click-right-icon="handleEnter"
                   @keypress.enter="handleEnter" placeholder="请输入内容"/>
      </div>
    </van-col>

  </van-row>
  <!-- 右侧弹出 -->
  <van-popup round v-model:show="showMemberInfo" close-icon-position="top-left" position="right"
             :style="{ width: '50%', height: '100%', position: 'absolute'}">
    <van-row>
      <van-col span="24" style="height: 10%;width:100%;position: relative">
        <van-cell-group inset >
          <van-cell title="总人数" :value="channelAllUserInfoList.length" />
          <van-cell title="在线人数" :value="channelAllUserInfoList.filter(k=>k.online).length" />
        </van-cell-group>
      </van-col>
      <van-col span="24" style=" width:100%;position: relative;">
        <VirtualList ref="headPicRef" :listData="channelAllUserInfoList.sort(onLineSort)"
                     :scrollHeight = "windowHeight * 0.9"
                     :itemHeight="windowHeight * 0.9 / 15"
                     v-slot:item="{item}"
        >
          <UserMessageListItem :item="item"/>
        </VirtualList>
      </van-col>
    </van-row>


  </van-popup>
</template>

<script lang="ts" setup>
import db from '@/utils/SessionStorage';
import httpRequest from '@/utils/HttpRequestUtils';
import MessageObject from '@/model/message/MessageObject';
import MessageHandlerManager from '@/proto/message/MessageHandlerManager';
import WebsocketUtils from '@/utils/WebsocketUtils';
import {
  ChannelMessageDTO,
  UserSendMessage_1004
} from "@/proto/ts/ChannelMessage";
import Long from "long";
import LongUtils from "@/utils/LongUtils";
import VirtualList from "@/components/VirtualList.vue";
import MessageListItem from "@/components/home/MessageListItem.vue";
import UserMessageListItem from "@/components/home/UserMessageListItem.vue";
import HomeTop from "@/components/home/HomeTop.vue";
import {onBeforeMount, ref, nextTick, computed} from "vue";
import {showNotify} from "vant";


const virtualMinSize = ref();

const showMemberInfo = ref(false);

const channelInfo = ref({});

const channelId = 1;

const content = ref('');

// 当前翻页
const page = 0;

const pageMessageSize = ref(12)


const pageSize = ref(10)

const msgList = ref([]);


// 用户频道信息
const channelAllUserInfo = ref({});
const channelAllUserInfoList = ref([]);

const currentLoginUserInfo = ref({});

const isFirstLoadData = ref(true);
const loadFinish = ref(false);

const windowWidth = ref();
const windowHeight = ref();
//首页获取到的最大id
const messageMaxId = ref(0);
const loading = ref(false)
const scrollBox = ref(null)
const headPicRef = ref(null)

/**
 * 组件图片是否加载完成
 */
const allImagesLoaded = ref(0);
const totalImages = computed(() => msgList.value.length);
const checkAllImagesLoaded = () => {
  //首次图片所以加载完成后需要滚动到底部
  if (allImagesLoaded.value === totalImages.value && isFirstLoadData.value) {
    toBottoms();
    isFirstLoadData.value = false;

  }
};

const onImageLoaded = () => {
  allImagesLoaded.value++;
  checkAllImagesLoaded();
};


const showChannelMemberInfo = () => {
  console.log("点击事件")
  showMemberInfo.value = !showMemberInfo.value;
  return showMemberInfo
}

const handleEnter = () => {
  console.log("回车事件")
  sendMsg();
}

const getChannelInfo = () => {
  const params = {
    channelId: channelId,
  };
  httpRequest.postForm('/api/channel/getChannelInfo', params).then((res) => {
    if (res.code === 0) {
      channelInfo.value = res.data;
    }
  });
}

const registerGuest = (msg : MessageObject) => {
  console.log('msg,', msg);
  const data = msg.decodeMessage;
  if (msg.msgId === 100) {
    const tokenWs = data.token;
    db.save('tokenWs', tokenWs);
    const userInfo = db.get('userInfo');
    const params = {
      id: !userInfo ? null : userInfo.id,
      tokenWs,
    };
    httpRequest.postForm('/api/user/registerGuest', params).then((res) => {
      if (res.code === 0) {
        db.save('userInfo', res.data);
        currentLoginUserInfo.value = userInfo;
        msgListToTop();
      }
    });
  }
}

const getNextPageMessageHistorySync = async (): any => {

  // page++
  let userInfo = db.get("userInfo");
  let result = httpRequest.postFormSync('/api/channel/getChannelHistoryMessage', {
    page: page,
    pageSize: pageSize.value,
    channelId: channelId,
    messageMaxId: messageMaxId.value,
  })
  let list = []

  await result.then((result) => {
    let res = result.data;
    if (res.code === 0) {
      let page = res.data;
      let pageData = page.records;
      for (let i = pageData.length - 1; i >= 0; i--) {
        let record = pageData[i];
        // console.log(" userInfo.id === record.userid,\n", userInfo.id === record.userid, channelAllUserInfo[record.userid])
        let msgInfo = {
          id: record.id,
          content: record.content,
          selfMsg: userInfo.id === record.userid,
          nickname: channelAllUserInfo.value[record.userid].nickname,
          headPic: channelAllUserInfo.value[record.userid].headPic,
        };
        list.push(msgInfo);
      }
      if (isFirstLoadData) {
        msgList.value = msgList.value.concat(list)
        messageMaxId.value = 9999999999;
        toBottoms();
      }
      for (let i = 0; i < list.length; i++) {
        messageMaxId.value = list[i].id < messageMaxId.value ? list[i].id : messageMaxId.value;
      }
      if (list.length == 0) {
        loadFinish.value = true;
      }
    }
  })

  return list;

}

const toBottoms =  () => {
  nextTick( () => {
    // await $refs.virtualListRef.scrollToBottom();
    scrollBox.value.scrollVirtualToBottom();

  })

}



const receiveMsg = (msg: any) => {
  const decodeMessage: MessageObject = msg.detail.data;
  const {msgId} = decodeMessage;
  console.log('组件接收内容', decodeMessage, msgId);
  registerGuest(decodeMessage);
  userJoinChannel(decodeMessage);
  addReceiveMsg(decodeMessage);
  handlerUserOnlineNotice(decodeMessage);
}

const addReceiveMsg = (messageObject: MessageObject) => {
  if (messageObject.msgId !== 1005) {
    return;
  }
  const userInfo = db.get('userInfo');
  const userReceiveMessage1005 = messageObject.decodeMessage;
  let message = userReceiveMessage1005.message;
  let messageUserid = LongUtils.protoLongToNumber(message.userid)
  console.log("接收用户发送的消息:", messageObject, userInfo, userInfo.id === messageUserid)


  const msgInfo = {
    id: parseInt(userInfo.id),
    content: message.content,
    selfMsg: parseInt(userInfo.id) === messageUserid,
    nickname: channelAllUserInfo.value[messageUserid].nickname,
    headPic: channelAllUserInfo.value[messageUserid].headPic,
  };
  msgList.value.push(msgInfo);
  if (parseInt(userInfo.id) === messageUserid) {
    toBottoms()
  }else{
    showNotify({
      message: msgInfo.nickname + ":" + msgInfo.content,
      color: '#ad0000',
      background: '#ffe1e1',
      duration: 2000,
      type: 'success'
    });
  }
}


const sendMsg = () => {
  let message: ChannelMessageDTO = {
    content: content.value,
    channelId: Long.fromNumber(channelId),
    type: 1,
    userid: Long.fromNumber(channelId),
    headPic: ""
  };

  const data: UserSendMessage_1004 = {
    message
  };
  const encode = MessageHandlerManager.encode(data, 1004);
  WebsocketUtils.sendWs(encode);
  content.value = '';
}

const getChannelUserInfo = () => {
  httpRequest.postForm('/api/channel/getChannelAllUser', {channelId: channelId}).then((res) => {
    console.log("getChannelAllUser", res)
    if (res.code === 0) {
      const model = res.data;
      for (let i = 0; i < model.length; i++) {
        // console.log("用户信息:", model[i].userid, model[i])
        channelAllUserInfo.value[model[i].userid] = model[i];
        channelAllUserInfoList.value.push(model[i])
        // break
      }
    }
  });
}

const msgListToTop = async () => {
  console.log("达到顶部，正在加载数据")
  if (loading.value || loadFinish.value) return;
  loading.value = true;
  const list = await getNextPageMessageHistorySync();
  if (!list || list.length === 0) {
    return list
  }
  // console.log(list);
  // msgList = list.concat(msgList);
  // msgList = msgList.concat(list);

  loading.value = false;
  return list;
}


const userJoinChannel = (message: MessageObject) => {
  if (message.msgId !== 1006) {
    return;
  }
  console.log('用户加入频道通知，', message);
  /**
   * @todo 没有区分频道
   */
  const decodeMessage = message.decodeMessage;
  let userid = LongUtils.protoLongToNumber(decodeMessage.userInfo.userid)
  let userInfo = {
    userid: userid ,
    nickname: decodeMessage.userInfo.nickname,
    online: false,
    rankName: '',
    headPic: decodeMessage.userInfo.headPic,
    level: null,
    score: '',
  };
  channelAllUserInfo.value[userid] = userInfo;
  channelAllUserInfoList.value.push(userInfo)

}

const handlerUserOnlineNotice = (messageObject: MessageObject) => {
  if (messageObject.msgId !== 1007) {
    return;
  }
  const message = messageObject.decodeMessage;
  const userid = LongUtils.protoLongToNumber(message.userid);
  const channelId = LongUtils.protoLongToNumber(message.channelId);

  console.log('用户在线状态', userid, message.online);

  if (channelId === channelId) {
    console.log('更改状态', channelAllUserInfo[userid], channelAllUserInfo);
    channelAllUserInfo.value[userid]['online'] = message.online;
  }

}
const onLineSort = (a, b) => {
  // 如果a.online是true且b.online不是，那么a应该在前面，返回-1
  if (a.online && !b.online) return -1;
  // 相反，如果b.online是true而a.online不是，则b应该在前面，返回1
  if (b.online && !a.online) return 1;
  // 如果两个的online状态相同，则保持原有顺序，返回0
  return 0;
}
onBeforeMount(() => {
    getChannelInfo();
    getChannelUserInfo();
    window.addEventListener('onmessageWS', receiveMsg);

    windowWidth.value = window.innerWidth;
    windowHeight.value = window.innerHeight;
    console.log("当前页面高度：", windowHeight.value, " 当前页面宽度:", windowWidth.value)
    virtualMinSize.value = windowHeight.value / pageMessageSize.value;
    pageSize.value = pageMessageSize.value * 1.5;
    console.log("每个聊天内容的宽度：", virtualMinSize.value, " 90%高度:", windowHeight.value * 0.9)
  }
)
</script>

<style scoped lang="scss">
#home-container {
  position: absolute;
  top: 0;
  height: 100%;
  width: 100%;
}


#all-msg-content {
  position: relative;
  height: 90%;
  //padding-top: 10%;
  //top: 5%;

  /*margin-bottom: 40px;*/
  //padding-bottom: 40px;
  //z-index: 0;
  //overflow-y: scroll;


}

//#list {
//  //padding-top: 10%;
//  padding-bottom: 10%;
//  //overflow-y: scroll;
//  width: 100%;
//}


#chat-bottom {
  position: relative;
  bottom: 0;
  width: 100%;
  /*z-index: 9999;*/
  background-color: #f7f7f7;
  /*height: 40px;*/
  /*height: 10%;*/
}

#chat-top {
  background-color: #F7f8FA;
  position: relative;
  top: 0;
  /*padding: 10px;*/
  //top: 0;
  width: 100%;
  height: 5%;
  z-index: 999;
}


</style>
